#pragma once

#include <map>

#include "IXTimer.h"
#include "IXTrayIcon.h"
#include "XBaseObjImpl.h"

class CXTrayIconMgrImpl : public CXBaseObjImpl<IXTrayIconMgr>, public IXTimer
{
    typedef CXBaseObjImpl<IXTrayIconMgr> superclass;
    DEF_SKIN_CLASS_SINGLE_INTF(CXTrayIconMgrImpl,
        superclass,
        gs_strGuidXSkin,
        IXTrayIconMgr,
        eIntf_Singleton);
public:
    CXTrayIconMgrImpl();
    virtual ~CXTrayIconMgrImpl();

    virtual UINT STDMETHODCALLTYPE AddIcon(XICON xIcon, LPCTSTR szTip, IXTrayIconCallback* pCallback, UINT uFlags);

    virtual BOOL STDMETHODCALLTYPE RemoveIcon(UINT uId);
    virtual void STDMETHODCALLTYPE RemoveAllIcon();
    virtual BOOL STDMETHODCALLTYPE ModifyIcon(UINT uId, XICON xIcon);
    virtual BOOL STDMETHODCALLTYPE ModifyIcon(UINT uId, LPCTSTR szText);
    virtual BOOL STDMETHODCALLTYPE PopTrayTip(UINT uId, LPCTSTR szTitle, LPCTSTR szText, UINT uTimeOut, DWORD dwIconType);
    virtual BOOL STDMETHODCALLTYPE HideTrayTip(UINT uId);

public:
    // IXTimer
    virtual void STDMETHODCALLTYPE   OnTimer(UINT_PTR uTimerId, void* pData);

public:
    // IXBaseObj
    virtual void STDMETHODCALLTYPE   OnConstruct();
    virtual void STDMETHODCALLTYPE   OnFinalRelease();

public:
    // CXTrayIconMgrImpl
    void    DelTrayIconCallback(IXTrayIconCallback* pCallback);

protected:
    void    AddWatchTimer(UINT uIconId, UINT uTimeOut, const NOTIFYICONDATA& _IconData);
    BOOL    IsTrayExists() const;

protected:
    HWND                    m_hTrayIconWnd;

    struct stIconInfo
    {
        XICON               xIcon;
        XString             strTip;
        UINT                uFlags;
        IXTrayIconCallback* pCallback;
    };
    typedef std::map<UINT, stIconInfo>    CallbackContainer;
    CallbackContainer       m_CallbackContainer;

    typedef struct
    {
        UINT uTimerId;
        UINT uRemainTime;
        NOTIFYICONDATA _IconData;
    } PopTrayTimerInfo;
    typedef std::map<UINT, PopTrayTimerInfo>    PopTrayTimerContainer;
    PopTrayTimerContainer   m_PopTrayTimerContainer;

protected:

    UINT    GetAutoId();

    HWND    GetTrayIconWnd();
    void    DeleteTrayIconWnd();

    virtual void OnTrayIconMessage(WPARAM wParam, LPARAM lParam);
    void    RestoreAllIcons();

    static LRESULT WINAPI TrayIconWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
};
